<template>
  <div class="container-publish">
    <el-card>
      <div slot="header">
        <my-bread>{{$route.query.id?'修改文章':'发布文章'}}</my-bread>
      </div>
      <!-- 表单 -->
      <el-form ref="articleForm" :model="articleForm" :rules="articleRules" label-width="120px">
        <el-form-item label="标题：" prop="title">
          <el-input v-model="articleForm.title" placeholder="请输入文章标题" style="width:400px"></el-input>
        </el-form-item>
        <el-form-item label="内容：" prop="content">
          <quill-editor
            @blur="checkContent()"
            v-model="articleForm.content"
            :options="editorOption"
          ></quill-editor>
        </el-form-item>
        <el-form-item label="封面：" prop="cover.type">
          <el-radio-group @change="articleForm.cover.images=[]" v-model="articleForm.cover.type">
            <el-radio :label="1">单图</el-radio>
            <el-radio :label="3">三图</el-radio>
            <el-radio :label="0">无图</el-radio>
            <el-radio :label="-1">自动</el-radio>
          </el-radio-group>
          <!-- 封面组件 -->
          <div style="height:162px" v-if="articleForm.cover.type===1">
            <my-image @afterConfirm="checkCover" v-model="articleForm.cover.images[0]"></my-image>
          </div>
          <div style="height:162px" v-if="articleForm.cover.type===3">
            <my-image @afterConfirm="checkCover" v-for="i in 3" :key="i" v-model="articleForm.cover.images[i-1]"></my-image>
          </div>
        </el-form-item>
        <el-form-item label="频道：" prop="channel_id">
          <my-channel v-model="articleForm.channel_id"></my-channel>
        </el-form-item>
        <el-form-item v-if="$route.query.id">
          <el-button @click="editArticle()" type="success">修改文章</el-button>
        </el-form-item>
        <el-form-item v-else>
          <el-button type="primary" @click="addArticle(false)">发布文章</el-button>
          <el-button @click="addArticle(true)">存入草稿</el-button>
        </el-form-item>
      </el-form>
    </el-card>
  </div>
</template>

<script>
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
// 导入组件配置
import { quillEditor } from 'vue-quill-editor'
export default {
  name: 'publish-page',
  components: { quillEditor },
  data () {
    // 自定义校验
    const checkCover = (rule, value, callback) => {
      // console.log(value, this.articleForm.cover.images)
      const images = this.articleForm.cover.images
      // 当你是单图的时候，图片组件中第一项必须有数据,长度只能是1
      if (value === 1) {
        if (!images[0] || images.length !== 1) {
          return callback(new Error('请选择一张封面图'))
        }
      }
      // 当你是三图的时候，图片组件中三项全部必须有数据
      if (value === 3) {
        if (!images[0] || !images[1] || !images[2]) {
          return callback(new Error('请选择三张封面图'))
        }
      }
      // 其他情况不必校验
      callback()
    }
    return {
      // 文章校验规则对象
      articleRules: {
        title: [
          { required: true, message: '请输入文章标题', trigger: 'blur' },
          { min: 5, max: 30, message: '文章标题5-30字符', trigger: 'blur' }
        ],
        content: [
          // 富文本组件不属于element-ui的表单元素组件，富文本的失去焦点
          // element-ui是监听不到，所以此时无法自动触发校验
          // 但是我们可以自己去监听富文本的失去焦点事件，在触发的时候手动去触发当前表单项的校验
          { required: true, message: '请输入文章内容', trigger: 'blur' }
        ],
        'cover.type': [
          // 因为cover是一个对象，需要自定义校验
          // 当cover当中的任何一个数据发生变化的时候，然后来进行校验
          // 使用 watch 侦听器监听 articleForm.cover 这个数据的变
          { validator: checkCover, trigger: 'change' }
        ],
        channel_id: [
          // 如果频道这个位置放置的是 el-select 组件, 那么触发的条件可以改成change
          { required: true, message: '请选择所属频道', trigger: 'change' }
        ]
      },
      // 文章表单数据对象
      articleForm: {
        // 文章标题
        title: null,
        cover: {
          // 封面类型
          type: 1,
          // 图片数组
          images: []
        },
        // 频道ID
        channel_id: null,
        // 文章内容
        content: null
      },
      // 富文本配置
      editorOption: {
        placeholder: '请输入文章内容',
        modules: {
          // 工具栏功能
          toolbar: [
            ['bold', 'italic', 'underline', 'strike'],
            ['blockquote', 'code-block'],
            [{ header: 1 }, { header: 2 }],
            [{ list: 'ordered' }, { list: 'bullet' }],
            [{ indent: '-1' }, { indent: '+1' }],
            ['image']
          ]
        }
      }
    }
  },
  watch: {
    // 监听地址栏ID的变化
    '$route.query.id': function () {
      if (this.$route.query.id) {
        // 填充表单
        this.getArticle()
      } else {
        // 重置表单
        this.$refs.articleForm.resetFields()
      }
    }
  },
  created () {
    // 以下两种情况都会触发，created
    // 1. 从内容管理点击编辑，跳转到组件
    // 2. 你在其他路由，点击发布文章，跳转到组件
    if (this.$route.query.id) {
      // 就是编辑文章场景
      this.getArticle()
    }
  },
  methods: {
    checkCover () {
      this.$refs.articleForm.validateField('cover.type')
    },
    // 修改文章
    editArticle () {
      this.$refs.articleForm.validate(async valid => {
        try {
          // 发送修改请求
          await this.$http({
            method: 'put',
            url: `/articles/${this.$route.query.id}`,
            // ?后键值对传参
            params: {
              draft: false
            },
            // 请求体传参
            data: this.articleForm
          })
          // 已经修改成功
          this.$message.success('修改文章成功')
          // 跳转内容管理
          this.$router.push('/article')
        } catch (e) {
          // 失败
          this.$message.error('修改文章失败')
        }
      })
    },
    // 获取文章数据
    async getArticle () {
      const { data: { data } } = await this.$http.get('/articles/' + this.$route.query.id)
      // 填充表单
      this.articleForm = data
    },
    // 校验富文本内容
    checkContent () {
      // 去触发表单项中 键名content的校验规则
      // 表单组件实例提供了 校验单项数据的函数
      this.$refs.articleForm.validateField('content')
    },
    // 添加
    addArticle (draft) {
      // 整体表单校验
      this.$refs.articleForm.validate(async valid => {
        if (valid) {
          // 进行添加
          try {
            // 请求
            // - query   地址上要键值对拼接 draft 数据
            // - body    请求主体传递  articleForm数据
            await this.$http.post(`/articles?draft=${draft}`, this.articleForm)
            // 成功
            this.$message.success(draft ? '存入草稿成功' : '发布文章成功')
            this.$router.push('/article')
          } catch (e) {
            // 失败
            this.$message.error(draft ? '存入草稿失败' : '发布文章失败')
          }
        }
      })
    }
  }
}
</script>

<style scoped lang='less'>
// 1. 把样式放进全局的样式
// 2. 让这段样式作用更深（在别人组件下的标签也能生效）vue-cli才支持
/deep/ .ql-toolbar.ql-snow {
  padding: 0 8px;
}
/deep/ .ql-editor {
  height: 250px;
}
</style>
